/*
 * @[H]:  Copyright (c) 2021 Phytium Information Technology, Inc. 
 * 
 *  SPDX-License-Identifier: Apache-2.0. 
 * 
 * @Date: 2021-08-03 13:35:05
 * @LastEditTime: 2021-08-05 18:13:13
 * @Description:  Description of file
 * @Modify History: 
 * * * Ver   Who        Date         Changes
 * * ----- ------     --------    --------------------------------------
 */

#ifndef DRIVERS_FPCIE_HW_H
#define DRIVERS_FPCIE_HW_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "ft_types.h"
#include "ft_io.h"

    /* config register */
#define FPCIE_REG_MISC_INT_STATE_OFFSET 0x00000008U
#define FPCIE_REG_MISC_INT_ENALBE_OFFSET 0x0000000CU
#define FPCIE_REG_MSI_ENABLE_OFFSET 0X000000200U
#define FPCIE_REG_MSI_UP32_ADDR_OFFSET 0X000000208U
#define FPCIE_REG_MSI_LOW32_ADDR_OFFSET 0X00000020CU
#define FPCIE_REG_MSI_SPI_ENABLE_OFFSET 0X000000608U
#define FPCIE_REG_MSI_SPI_DATA_OFFSET 0X00000060CU
#define FPCIE_REG_EP_C0_PREF_BASE_LIMIT_OFFSET 0X000000A30U
#define FPCIE_REG_EP_C0_PREF_BASE_LIMIT_UP32_OFFSET 0X000000A34U
#define FPCIE_REG_EP_C0_MEM_BASE_LIMIT_OFFSET 0X000000A38U
#define FPCIE_REG_EP_C1_PREF_BASE_LIMIT_OFFSET 0X000000A40U
#define FPCIE_REG_EP_C1_PREF_BASE_LIMIT_UP32_OFFSET 0X000000A44U
#define FPCIE_REG_EP_C1_MEM_BASE_LIMIT_OFFSET 0X000000A48U
#define FPCIE_REG_EP_C2_PREF_BASE_LIMIT_OFFSET 0X000000A50U
#define FPCIE_REG_EP_C2_PREF_BASE_LIMIT_UP32_OFFSET 0X000000A54U
#define FPCIE_REG_EP_C2_MEM_BASE_LIMIT_OFFSET 0X000000A58U

    /* Controler register */
#define FPCIE_REG_MSI_LOW_ADDRESS_OFFSET 0x94U     /* MSI 事务的写地址低 32 位 */
#define FPCIE_REG_MSI_HIGH_ADDRESS_OFFSET 0x98U    /* MSI 事务的写地址高 32 位 */
#define FPCIE_REG_MSI_DATA_OFFSET 0x9CU            /* MSI 事务携带的数据信息 */
#define FPCIE_REG_OUTBOUND_R0_PATR0_OFFSET 0x8000U /* 控制器输出方向上 region 0 的转换后地址低 32 位 */
#define FPCIE_REG_OUTBOUND_R0_PATR1_OFFSET 0x8004U /* 控制器输出方向上 region 0 的转换后地址高 32 位 */
#define FPCIE_REG_OUTBOUND_R0_PHDR0_OFFSET 0x8008U /* 控制器输出方向上 region 0 的转换描述符[31:0]位  */
#define FPCIE_REG_OUTBOUND_R0_PHDR1_OFFSET 0x800CU /* 控制器输出方向上 region 0 的转换描述符[63:31]位 */
#define FPCIE_REG_OUTBOUND_R0_PHDR2_OFFSET 0x8010U /* 控制器输出方向上 region 0 的转换描述符[95:64]位 */
#define FPCIE_REG_OUTBOUND_R0_ARBA0_OFFSET 0x8018U /* 控制器输出方向上 region 0 的转换前的地址低 32 位 */
#define FPCIE_REG_OUTBOUND_R0_ARBA1_OFFSET 0x801CU /* 控制器输出方向上 region 0 的转换前的地址高 32 位 */
#define FPCIE_REG_F0_B0_ATR_L_OFFSET 0x8840U       /* 控制器 FUNC 0 BAR 0 地址转换寄存器低 32 位 */
#define FPCIE_REG_F0_B0_ATR_H_OFFSET 0x8844U       /* 控制器 FUNC 0 BAR 0 地址转换寄存器高 32 位 */
#define FPCIE_REG_F0_B2_ATR_L_OFFSET 0x8850U       /* 控制器 FUNC 0 BAR 2 地址转换寄存器低 32 位 */
#define FPCIE_REG_F0_B2_ATR_H_OFFSET 0x8854U       /*  控制器 FUNC 0 BAR 2 地址转换寄存器高 32 位 */
#define FPCIE_REG_DMA_CH0_CTRL_OFFSET 0xC000U      /* DMA channel 0 的控制器寄存器 */
#define FPCIE_REG_DMA_CH0_SP_L_OFFSET 0xC004U      /* DMA channel 0 描述符存储的首地址低 32 位寄存器 */
#define FPCIE_REG_DMA_CH0_SP_H_OFFSET 0xC008U      /* DMA channel 0 描述符存储的首地址高 32 位寄存器 */
#define FPCIE_REG_DMA_CH1_CTRL_OFFSET 0xC014U      /* DMA channel 1 的控制器寄存器 */
#define FPCIE_REG_DMA_CH1_SP_L_OFFSET 0xC018U      /* DMA channel 1 描述符存储的首地址低 32 位寄存器 */
#define FPCIE_REG_DMA_CH1_SP_H_OFFSET 0xC01CU      /* DMA channel 1 描述符存储的首地址高 32 位寄存器 */
#define FPCIE_REG_DMA_INT_STATUS_OFFSET 0xC0A0U    /* DMA 中断状态寄存器 */
#define FPCIE_REG_DMA_INT_ENABLE_OFFSET 0xC0A4U    /* DMA 使能寄存器 */

    /* REG_MISC_INT_STATE */
#define FPCIE_MISC_STATE_C0_DMA_INT_MASK 0x1U
#define FPCIE_MISC_STATE_C0_LOCAL_INT_MASK 0x2U
#define FPCIE_MISC_STATE_C0_POWER_STATE_CHANGE_MASK 0x4U
#define FPCIE_MISC_STATE_C1_DMA_INT_MASK 0x100U
#define FPCIE_MISC_STATE_C1_LOCAL_INT_MASK 0x200U
#define FPCIE_MISC_STATE_C1_POWER_STATE_CHANGE_MASK 0x400U
#define FPCIE_MISC_STATE_C2_DMA_INT_MASK 0x1000U
#define FPCIE_MISC_STATE_C2_LOCAL_INT_MASK 0x2000U
#define FPCIE_MISC_STATE_C2_POWER_STATE_CHANGE_MASK 0x4000U

    /* REG_MISC_INT_ENALBE */
#define FPCIE_MISC_ENALBE_C0_MISC_INT_EN_MASK 0x1U
#define FPCIE_MISC_ENALBE_C1_MISC_INT_EN_MASK 0x2U
#define FPCIE_MISC_ENALBE_C2_MISC_INT_EN_MASK 0x4U

    /* REG_MSI_ENABLE */
#define FPCIE_MSI_EN_MASK 0x1U

    /* REG_MSI_UP32_ADDR */
#define FPCIE_MSI64_HI_ADDR_OFFSET 0xFFFFFFFFU

    /* REG_MSI_LOW32_ADDR */
#define FPCIE_MSI64_LO_ADDR_MASK 0xFFFF0000U

    /* REG_MSI_SPI_ENABLE */
#define FPCIE_MSI_DATA_MASK 0xFFFFU
#define FPCIE_MSI_DEVICE_ID_MASK 0xFFFF0000U

    /* REG_EP_C0_PREF_BASE_LIMIT */
#define FPCIE_C0_PREF_BASE_MASK 0xfff0U
#define FPCIE_C0_PREF_LIMIT_MASK 0xfff00000U

    /* REG_EP_C0_PREF_BASE_LIMIT_UP32 */
#define FPCIE_C0_PREF_BASE_UP32_MASK 0xFFU
#define FPCIE_C0_PREF_LIMIT_UP32_MASK 0xFF00U

    /* REG_EP_C1_PREF_BASE_LIMIT */
#define FPCIE_C1_PREF_BASE_MASK 0xfff0U
#define FPCIE_C1_PREF_LIMIT_MASK 0xfff00000U

    /* REG_EP_C1_PREF_BASE_LIMIT_UP32 */
#define FPCIE_C1_PREF_BASE_UP32_MASK 0xFFU
#define FPCIE_C1_PREF_LIMIT_UP32_MASK 0xFF00U

    /* Controler register */
    /* REG_MSI_LOW_ADDRESS */
#define FPCIE_CTRL_MSI_LOW_ADDR_MASK 0XFFFFFFFCU

    /* REG_MSI_HIGH_ADDRESS */
#define FPCIE_CTRL_MSI_HIGH_ADDR_MASK 0XFFFFFFFFU

    /* REG_MSI_DATA */
#define FPCIE_CTRL_MESSAGE_DATA_MASK 0xffffU

    /* REG_OUTBOUND_R0_PATR0 */
#define FPCIE_CTRL_OUTBOUND_R0_PATR0_R0_NUM_BITS_MASK 0x1fU
#define FPCIE_CTRL_OUTBOUND_R0_PATR0_ADDR_BITS_MASK 0xffffff00U

    /* REG_OUTBOUND_R0_PATR1 */
#define FPCIE_CTRL_OUTBOUND_R0_PATR1_ADDR_BITS_MASK 0xffffffffU

    /* REG_OUTBOUND_R0_PHDR0 */
#define FPCIE_CTRL_OUTBOUND_R0_PHDR0_DESCRIPTOR_MASK 0xffffffffU

    /* REG_OUTBOUND_R0_PHDR1 */
#define FPCIE_CTRL_OUTBOUND_R0_PHDR1_DESCRIPTOR_MASK 0xffffffffU

    /* REG_OUTBOUND_R0_PHDR2 */
#define FPCIE_CTRL_OUTBOUND_R0_PHDR2_DESCRIPTOR_MASK 0x1fffU

    /* REG_OUTBOUND_R0_ARBA0 */
#define FPCIE_CTRL_OUTBOUND_R0_ARBA0_LOWER_MASK 0x3f
#define FPCIE_CTRL_OUTBOUND_R0_ARBA0_ADDR_MASK 0XFFFFFFF0U

    /* REG_OUTBOUND_R0_ARBA1 */
#define FPCIE_CTRL_OUTBOUND_R0_ARBA1_ADDR_MASK 0xffffffffU

    /* REG_F0_B0_ATR_L */
#define FPCIE_CTRL_F0_B0_ATR_L_ADDR_MASK 0xffffffffU

    /* REG_F0_B0_ATR_H */
#define FPCIE_CTRL_F0_B0_ATR_H_ADDR_MASK 0xffffffffU

    /* REG_F0_B2_ATR_L */
#define FPCIE_CTRL_F0_B2_ATR_L_ADDR_MASK 0xffffffffU

    /* REG_F0_B2_ATR_H */
#define FPCIE_CTRL_F0_B2_ATR_H_ADDR_MASK 0xffffffffU

    /* REG_DMA_CH0_CTRL */
#define FPCIE_CTRL_DMA_CH0_CTRL_GO_MASK 0x1U
#define FPCIE_CTRL_DMA_CH0_CTRL_OBNOTIB_MASK 0x2U

    /* REG_DMA_CH0_SP_L */
#define FPCIE_CTRL_DMA_CH0_SP_L_START_MASK 0XFFFFFFFFU

    /* REG_DMA_CH0_SP_H */
#define FPCIE_CTRL_DMA_CH0_SP_H_START_MASK 0XFFFFFFFFU

    /* REG_DMA_CH1_CTRL */
#define FPCIE_CTRL_DMA_CH1_CTRL_GO_MASK 0x1U
#define FPCIE_CTRL_DMA_CH1_CTRL_OBNOTIB_MASK 0x2U

    /* REG_DMA_CH1_SP_L */
#define FPCIE_CTRL_DMA_CH1_SP_L_START_MASK 0XFFFFFFFFU

    /* REG_DMA_CH1_SP_H */
#define FPCIE_CTRL_DMA_CH1_SP_H_START_MASK 0XFFFFFFFFU

    /* REG_DMA_INT_STATUS */
#define FPCIE_CTRL_DMA_INT_STATUS_CH0_DONE_MASK 0x1U
#define FPCIE_CTRL_DMA_INT_STATUS_CH1_DONE_MASK 0x2U
#define FPCIE_CTRL_DMA_INT_STATUS_CH0_ERR_MASK 0x10U
#define FPCIE_CTRL_DMA_INT_STATUS_CH1_ERR_MASK 0x20U
#define FPCIE_CTRL_DMA_INT_STATUS_ALL_MASK (FPCIE_CTRL_DMA_INT_STATUS_CH0_DONE_MASK | FPCIE_CTRL_DMA_INT_STATUS_CH1_DONE_MASK | FPCIE_CTRL_DMA_INT_STATUS_CH0_ERR_MASK | FPCIE_CTRL_DMA_INT_STATUS_CH1_ERR_MASK)

    /* REG_DMA_INT_ENABLE */
#define FPCIE_CTRL_DMA_INT_ENABLE_CH0_DONE_MASK 0x1U
#define FPCIE_CTRL_DMA_INT_ENABLE_CH1_DONE_MASK 0x2U
#define FPCIE_CTRL_DMA_INT_ENABLE_CH0_ERR_MASK 0x10U
#define FPCIE_CTRL_DMA_INT_ENABLE_CH1_ERR_MASK 0x20U
#define FPCIE_CTRL_DMA_INT_ENABLE_ALL_MASK (FPCIE_CTRL_DMA_INT_ENABLE_CH0_DONE_MASK | FPCIE_CTRL_DMA_INT_ENABLE_CH1_DONE_MASK | FPCIE_CTRL_DMA_INT_ENABLE_CH0_ERR_MASK | FPCIE_CTRL_DMA_INT_ENABLE_CH1_ERR_MASK)

/** @name ECAM Address Register bitmaps and masks
 *
 * @{
 */
#define FPCIE_ECAM_MASK 0x0FFFFFFF     /**< Mask of all valid bits */
#define FPCIE_ECAM_BUS_MASK 0x0FF00000 /**< Bus Number Mask */
#define FPCIE_ECAM_DEV_MASK 0x000F8000 /**< Device Number Mask */
#define FPCIE_ECAM_FUN_MASK 0x00007000 /**< Function Number Mask */
#define FPCIE_ECAM_REG_MASK 0x00000FFC /**< Register Number Mask */
#define FPCIE_ECAM_BYT_MASK 0x00000003 /**< Byte Address Mask */

#define FPCIE_ECAM_BUS_SHIFT 20 /**< Bus Number Shift Value */
#define FPCIE_ECAM_DEV_SHIFT 15 /**< Device Number Shift Value */
#define FPCIE_ECAM_FUN_SHIFT 12 /**< Function Number Shift Value */
#define FPCIE_ECAM_REG_SHIFT 2  /**< Register Number Shift Value */
#define FPCIE_ECAM_BYT_SHIFT 0  /**< Byte Offset Shift Value */
/*@}*/

/**
*
* This macro reads the given register.
*
* @param    base_addr is the base address of the device.
* @param    reg_offset is the register offset to be read.
*
* @return   The 32-bit value of the register
*
* @note     None.
*
*****************************************************************************/
#define FPCIE_READREG(base_addr, reg_offset) \
    FtIn32((base_addr) + (u32)(reg_offset))

/****************************************************************************/
/**
*
* This macro writes the given register.
*
* @param    base_addr is the base address of the device.
* @param    reg_offset is the register offset to be written.
* @param    data is the 32-bit value to write to the register.
*
* @return   None.
*
* @note     None.
*
*****************************************************************************/
#define FPCIE_WRITEREG(base_addr, reg_offset, data) \
    FtOut32((base_addr) + (u32)(reg_offset), (u32)(data))

#define FPCIE_SETBIT(base_addr, reg_offset, data) \
    FtSetBit32((base_addr) + (u32)(reg_offset), (u32)(data))

#define FPCIE_CLEARBIT(base_addr, reg_offset, data) \
    FtClearBit32((base_addr) + (u32)(reg_offset), (u32)(data))

#ifdef __cplusplus
}
#endif

#endif // !